package com.hulk.ratel.manage.interceptor;

import com.google.common.base.Throwables;
import com.hulk.ratel.common.constant.enums.BussErrCode;

import com.hulk.ratel.common.exception.BaseRteException;
import com.hulk.ratel.common.exception.ManageRteException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.dao.CannotAcquireLockException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 定义异常处理的切面
 * 
 * @author hulk
 * 
 */
 @Component
 @Order(4)
 @Aspect
@Slf4j
public class AfterThrowingAdvice {
	/**
	 * 添加业务逻辑方法切入点
	 */
	// 这个表达式现在配置错误， 应该只拦截 service 下面的类，在service子包的类就不拦截了 execution(*
	// com.hulk.boot.service..*.*(..) //TODOcom.hulk.ratel.manage.transactionservice
	// @Pointcut("execution(public * com.hulk.boot.service.*.*(..))")
	@Pointcut("execution(* com.hulk.ratel.manage.commonservice.*.*(..))"
			+ "&& execution(* com.hulk.ratel.manage.transactionservice.*.*(..))"
			+ "&& execution(* com.hulk.ratel.manage.commoncache.*.*(..))")
	public void allService() {
		// http://edu.51cto.com/lesson/id-36989.html
	}

	@Around(value = "allService()")  //@AfterThrowing 使用这个 性能上是否有区别
	public Object transferException(ProceedingJoinPoint pjp) {

		String clazzName = pjp.getClass().toGenericString();
		MethodSignature signature = (MethodSignature) pjp.getSignature();
		Method method = signature.getMethod();
		log.debug("pjp  occurred..............clazzName:{}, method:{},params:{}",
				new Object[] { clazzName, method.toGenericString(), pjp.getArgs(), });
		// Class<?> methodReturnType = method.getReturnType();
		Object result = null;
		String errorCode = null;
		String errorMsg = null;

		try {
			result = pjp.proceed();
		} catch (Throwable e) {
			log.error("transferException  occurred..............clazzName:{}, method:{},params:{},cause:{}",
					new Object[] { clazzName, method.toGenericString(), pjp.getArgs(),
							Throwables.getStackTraceAsString(e) });
		   if (e instanceof BaseRteException) {
				errorCode = ((BaseRteException) e).getErrorCode();
				errorMsg = ((BaseRteException) e).getErrorMessage();
			} else if (e instanceof DataIntegrityViolationException) {
				if (e.toString().contains("ORA-00001")) {
					errorCode = BussErrCode.E_900007.getErrCode();
					errorMsg = BussErrCode.E_900007.getErrDesc();
				} else {
					errorCode = BussErrCode.E_900008.getErrCode();
					errorMsg = BussErrCode.E_900008.getErrDesc();
				}
			} else if (e instanceof CannotAcquireLockException) {
				errorCode = BussErrCode.E_900009.getErrCode();
				errorMsg = BussErrCode.E_900009.getErrDesc();
			} else {
				errorCode = BussErrCode.E_999999.getErrCode();
				errorMsg = BussErrCode.E_999999.getErrDesc();
			}
			throw new ManageRteException("", errorCode, errorMsg, e);
		}

		return result;

	}

	// 因为 异常通知没有返回值 即使返回参数不为void 也没用， 所以这种方式不能使用
	/*
	 * @AfterThrowing( value = "allService()", throwing = "e") public void
	 * doException(JoinPoint jp, Exception e) { ResponseWrapper<Object> result =
	 * null; try { org.aspectj.lang.Signature signature = jp.getSignature();
	 * String name = signature.getName(); Method method = ((MethodSignature)
	 * signature).getMethod();
	 * 
	 * if (e != null) { log.
	 * error("transferException  occurred..............name:{}, method:{},params:{},cause:{}"
	 * , new Object[] { name, method.toGenericString(), jp.getArgs(),
	 * Throwables.getStackTraceAsString(e) }); // if
	 * (methodReturnType.isAssignableFrom(ResponseWrapper.class)) { String
	 * errorCode = null; String errorMsg = null; if (e instanceof BaseException)
	 * { errorCode = ((BaseException) e).getErrorCode(); errorMsg =
	 * ((BaseException) e).getErrorMessage(); } else if (e instanceof
	 * BaseRteException) { errorCode = ((BaseRteException) e).getErrorCode();
	 * errorMsg = ((BaseRteException) e).getErrorMessage(); } else if (e
	 * instanceof DataIntegrityViolationException) { if
	 * (e.toString().contains("ORA-00001")) { errorCode =
	 * BussErrCode.E_900007.getErrCode(); errorMsg = BussErrCode.E_900007.getErrDesc();
	 * } else { errorCode = BussErrCode.E_900008.getErrCode(); errorMsg =
	 * BussErrCode.E_900008.getErrDesc(); } } else if (e instanceof
	 * CannotAcquireLockException) { errorCode = BussErrCode.E_900009.getErrCode();
	 * errorMsg = BussErrCode.E_900009.getErrDesc(); } else { errorCode =
	 * BussErrCode.E_999999.getErrCode(); errorMsg = BussErrCode.E_999999.getErrDesc();
	 * } result = new ResponseWrapper<Object>(errorCode, errorMsg); log.
	 * error("transferException  occurred..............name:{},method:{},params:{},ResponseWrapper:{},cause:{}"
	 * , new Object[] { name, method.toGenericString(), jp.getArgs(), result,
	 * Throwables.getStackTraceAsString(e) }); } } catch (Exception e1) { String
	 * errorCode = BussErrCode.E_999999.getErrCode(); String errorMsg =
	 * BussErrCode.E_999999.getErrDesc(); result = new
	 * ResponseWrapper<Object>(errorCode, errorMsg); }
	 * 
	 * }
	 */
}
